# Client Matter — Execution flow
This page describes the step-by-step execution of ClientMatterInformationHandler.Execute(), the orchestrator that runs every time a Client Matter file is processed. Steps are numbered in execution order.
# 1. Input validation
If no CreateUpdateClientMatter object is present, execution stops immediately with a failure result.
# 2. Existing-matter lookup
When a MatterCode is present, the handler queries the MattersList to check whether this matter has been provisioned before. The query returns the matter's stored URL, site URL, and the ClientMatterDesign that was used to create it.
The result drives two decisions:
- Design detection — if a design is stored in the MattersList entry (in the
ClientMatterStructurecolumn), it is applied to the current request before any other design resolution runs. This guarantees that updates always use the same structural design as the original provisioning. - New vs. existing distinction — see step 4 below.
If MatterCodeIsNotUnique is enabled in the configuration, matter codes are not globally unique — the same matter code can exist under different clients. In that case, the handler first queries the client list to obtain the client's list item ID, then uses the combination of that client ID and the matter code to find the correct matter entry in the MattersList.
# 3. MonitorDirectory routing
MonitorDirectory signals that the current service instance should not process this request locally — instead, it should forward the JSON file to a different service instance (one watching that directory) that owns the correct configuration for this matter.
Routing triggers under two conditions:
No MatterCode: If MatterCode is empty and MonitorDirectory is set, the handler clears the MonitorDirectory field, saves the JSON to that directory, and returns success. Since no code is present, the receiving instance handles code assignment and provisioning.
This path only applies to JSON requests; Excel rows always have a MatterCode.
MatterCode present: After the existing-matter lookup (step 2), if MonitorDirectory is set, the handler evaluates the matter's stored URL:
| MattersList URL state | Action |
|---|---|
Not found (null) | Calls ParseMatterStatus; if matter is Closed, stops with success — no point forwarding a closed matter that was never provisioned. Otherwise routes. |
| Empty string (no URL yet) | Routes to MonitorDirectory. |
Starts with http (already provisioned) | Routes to MonitorDirectory — the receiving instance handles the update in the correct environment. |
| Non-HTTP local path (intermediate state) | Routing is skipped. Execution continues locally on the current service instance. |
When routing, the MonitorDirectory field is cleared from the request before saving, so the receiving instance processes it as a normal local request.
# 4. New vs. existing matter
The stored URL from the MattersList lookup (step 2) determines the processing path:
| URL state | Meaning | Behaviour |
|---|---|---|
null (not found) | New matter | Full provisioning path; config switching allowed |
| Empty string | In MattersList but no URL yet | Treated as new |
Starts with http | Already provisioned | Update path; original SharepointCfg is kept |
| Other (local path) | Intermediate state | Local processing continues with current config |
Update path: when a matter already has a provisioned URL, the SharepointCfg is locked to the one originally used (the one whose SharePoint environment contains the matter). Config switching (step 5) is skipped. This ensures updates always run against the original environment.
# 5. Configuration switching
If the request specifies a SharepointCfg name different from the current configuration, and the matter is new (not yet provisioned), the handler loads and clones that configuration and uses it for the rest of execution. This allows a single service instance to provision matters across multiple SharePoint environments based on per-matter input.
For existing (already-provisioned) matters, configuration switching is skipped — the original config is always kept so updates land in the correct environment.
# 6. Auto-numbering
If ClientCodeStartNumber is configured and no ClientCode was provided, the handler calls AutoNumber.GetNextID to assign the next available client code. The same applies to MatterCode when MatterCodeStartNumber is configured.
When either code is auto-assigned and the request was loaded from a JSON file, the file is overwritten with the assigned codes so the source file reflects what was actually used.
After this step, if both ClientCode and MatterCode are still empty, execution stops with a failure result.
See Auto-numbering for a full description of format strings, counter storage, and reset behaviour.
# 7. Dynamic ClientMatterStructure and URL resolution
Two values are resolved through the GetDynamicNameValue pipeline, which evaluates dynamic placeholders (tokens from the matter's properties) against the configuration:
ClientMatterStructure— resolves the matter structure/design name. If the resolved value matches a knownClientMatterDesignenum, it overrides the design for this execution.ClientMatterServerRelativeUrl— resolves the root server-relative URL under which the matter site or library will be created.
Both values can be static strings or dynamic expressions referencing matter properties such as client code, matter type, or area of law.
After dynamic resolution, explicit overrides from the request are applied:
- If
ClientMatterDesignis set on the request, it overrides the configuration's design value. - If
ServerRelativeUrlis set on the request, it overrides the resolved server-relative URL.
# 8. Matter status parsing
ParseMatterStatus reads the matter's status value from its properties and maps it to either Open or Closed using the configuration below. If the feature is not configured, the status remains unset and all operations proceed unconditionally.
| Configuration property | Description |
|---|---|
SettingsCfg.Provisioning.MatterStatusColumnName | Name of the column in the MattersList that holds the status value. Leave empty to disable status-based behaviour entirely. |
SettingsCfg.Provisioning.MatterStatusOpenedValues | Array of column values that mean the matter is open (e.g. ["Opened", "Geopend"]). |
SettingsCfg.Provisioning.MatterStatusClosedValues | Array of column values that mean the matter is closed (e.g. ["Closed", "Gesloten"]). At least one value must be configured here for status parsing to activate. |
The status value is read from the matter's properties using MatterStatusColumnName. It is matched case-insensitively against MatterStatusClosedValues first, then MatterStatusOpenedValues. If no match is found the status remains unset.
The resolved status is used in two places:
- Step 3 (MonitorDirectory routing): if a matter is not in the MattersList and is
Closed, execution stops immediately — there is no point routing a matter that was already closed before it was ever provisioned. - Design handler execution (step 10): when a matter is
Closed, design handlers setSkipIfNotExists = trueon the matter list and site/library operations. This means a closed matter can only update structures that already exist — it cannot create new sites, libraries, or list items.
# 9. Design handler selection
The handler selects an IClientMatterDesignHandler based on ClientMatterDesign:
| Design | SharePoint structure |
|---|---|
MatterSiteCollection | Matter gets its own top-level site collection |
MatterSite | Matter is a sub-site within an existing site collection |
MatterDocLib | Matter is a document library within an existing site |
ClientSiteCollection_MatterSite | Client has its own site collection; matter is a sub-site within it |
ClientSiteCollection_MatterDocLib | Client has its own site collection; matter is a document library within it |
ClientSite_MatterSite | Client has a site (not a full site collection); matter is a sub-site within it |
ClientSite_MatterDocLib | Client has a site; matter is a document library within it |
MatterOffice365Group | Matter is a Microsoft 365 Group/Team (SharePoint Online only) |
If no handler is found for the configured design, an exception is thrown.
# Round-robin URL selection
When SharepointRootServerRelativeUrl is configured as a semicolon-separated list of multiple URLs, the handler distributes matters across those URL prefixes using a round-robin algorithm (GetSharepointRootServerRelativeUrl). The algorithm counts existing sites under each URL and picks the one with the fewest matters, refreshing its counts when they become stale. Access is serialised per configuration to prevent two concurrent requests from selecting the same target URL.
# 10. Design handler execution
The selected design handler runs and returns an ActionResult. The handler flags (ClientCreated, MatterCreated, ClientListItemCreated, MatterListItemCreated) are propagated back to the caller after execution.
# 11. Post-success steps
The following steps run only when the design handler reports success.
# My Matters list
The matter's entry in the My Matters list is renamed if the matter name changed. The previous name is read from the MatterName column of the existing matter list item (falling back to Title with the code prefix stripped if MatterName is empty). The previous title is then stripped of any client name prefix before the rename to avoid double-prefixing (e.g. Acme - Contract review → Contract review).
See Matter list title columns for how MatterName, Title, and NormalizedTitle relate and how the title format is configured.
# Extranet integration
If an extranet is configured, ICreateUpdateExtranet builds a duplicate provisioning request targeting the extranet environment (adjusting codes, names, design, and URL), dispatches it to the correct service instance, and writes the assigned extranet matter code back into the original matter's list entry.
See Extranet integration for the full description of both extranet modes, column mapping, external dispatch, and all configuration properties.
# Client and matter URL write-back
The absolute URLs of the matter site and document library (URL, SiteURL, Epona365URL) are written back into the matter's properties so subsequent steps and list updates can use the final SharePoint addresses.
For designs with a client site or site collection, the client SiteURL is also written back.
# Master monitor directory (optional)
If SettingsCfg.Provisioning.MatterListMonitorDirectory is configured, the handler writes two JSON files to that directory:
ClientList_<ClientCode>.json— client properties for the master environment's client listMatterList_<ClientCode>_<MatterCode>.json— matter properties for the master environment's matter list
This allows a secondary service instance (watching the master directory) to keep its own client/matter lists in sync after the matter is provisioned in the primary environment.
# Update default values (optional)
If SettingsCfg.Provisioning.UpdateDefaultValuesOnDocumentsMonitorDirectory is configured, the handler writes an AssignDefaultValuesInDocLib_<ClientCode>_<MatterCode>.json file to that directory. This triggers the Update Default Values job to apply the matter's metadata as default column values on all existing documents in the matter's document libraries.
If a file with identical content already exists at that path, the write is skipped to avoid unnecessary reprocessing.
# 12. Finally: post-handlers and lock release
Regardless of success or failure, the finally block runs:
- Post-handlers — all registered
IClientMatterPostHandlerimplementations are invoked in sequence. Each receives the connection, the action result, and theCreateUpdateClientMatterobject. Errors in individual post-handlers are caught and logged but do not affect the overall result. - Lock release — concurrency locks held for the client code and the client/matter code pair are released, allowing any queued requests for the same matter to proceed.
# Client and matter identifiers
Each client and matter has two separate identifiers that serve different purposes.
ClientCode / MatterCode are the functional codes used throughout provisioning: SharePoint list lookups, site URL generation, filenames, log output, and concurrency lock keys.
ClientID / MatterID are external system identifiers supplied by the originating system (case management, ERP, etc.). They are stored in the ExternalID column of the client list and matter list respectively.
# Lookup priority
When CreateOrUpdateItem runs against a SharePoint list:
- If
ClientID/MatterIDis provided and the list has anExternalIDcolumn — the list item is looked up byExternalID. TheCodecolumn is still written but is not used for matching. - Otherwise — the list item is looked up by
Code(ClientCode/MatterCode). - If
Codeis empty,ExternalIDis used as the code value as a fallback.
This means a matter is found by its external system ID even if its code changes over time — as long as the ExternalID column exists in the list and the ID is supplied on each request.
# Related links
- Client Matter handler — columns, format reference, and filename pattern
- Matter List handler — create or update matter list entries without full provisioning
- Client List handler — create or update client list entries without full provisioning